package com.github.abel533.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;

import static com.github.abel533.C.print;

@Configuration
public class PostProcessorImpl implements EnvironmentPostProcessor, BeanFactoryPostProcessor,
    BeanPostProcessor, InstantiationAwareBeanPostProcessor, SmartInstantiationAwareBeanPostProcessor {

    /**
     * EnvironmentPostProcessor
     */
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        print("EnvironmentPostProcessor#postProcessEnvironment");
    }

    //<editor-fold desc="InstantiationAwareBeanPostProcessor">
    //<editor-fold desc="BeanPostProcessor">
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        print("BeanPostProcessor#postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        print("BeanPostProcessor#postProcessAfterInitialization");
        return bean;
    }
    //</editor-fold>

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        print("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        print("InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation");
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        print("InstantiationAwareBeanPostProcessor#postProcessProperties");
        return null;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        print("InstantiationAwareBeanPostProcessor#postProcessPropertyValues");
        return pvs;
    }
    //</editor-fold>


    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        //print("SmartInstantiationAwareBeanPostProcessor#predictBeanType");
        return null;
    }

    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        print("SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors");
        return null;
    }

    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        print("SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference");
        return bean;
    }

    /**
     * BeanFactoryPostProcessor
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        print("BeanFactoryPostProcessor#postProcessBeanFactory");
    }

    /*

    8 : org/springframework/beans/factory/config/DestructionAwareBeanPostProcessor.class
   9 : org/springframework/beans/factory/support/MergedBeanDefinitionPostProcessor.class
  10 : org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor.class
     */


}
